<?php
/**
 * Created By Leroi Liu
 * Email：675667823@qq.com
 * Date：2023/2/12
 * Description：
 **/
// 应用公共文件
if (!function_exists('model')){
    function model($table=''){
        return \think\facade\Db::table($table);
    }
}
if (!function_exists('modelStartTrans')){
    function modelStartTrans(){
        \think\facade\Db::startTrans();
    }
}
if (!function_exists('modelCommit')){
    function modelCommit(){
        \think\facade\Db::commit();
    }
}
if (!function_exists('modelRollback')){
    function modelRollback(){
        \think\facade\Db::rollback();
    }
}
if (!function_exists('json_success')){
    function json_success($data=[],$message='结果请求获取成功',$code=200,$toast=0){
        return json(['code'=>$code,'message'=>$message,'data'=>$data,'toast'=>$toast]);
    }
}
if (!function_exists('json_error')){
    function json_error($message='结果请求获取失败',$data=[],$code=500,$toast=1){
        return json(['code'=>$code,'message'=>$message,'data'=>$data,'toast'=>$toast]);
    }
}
if (!function_exists('exit_error')) {
    function exit_error($message = '结果请求获取失败', $data = [], $code = 500,$toast=1)
    {
        $header['Access-Control-Allow-Origin']  = app('request')->header('origin');
        $header['Access-Control-Allow-Headers'] = 'Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With, Token';
        $header['Access-Control-Max-Age'] = '1800';
        $header['Access-Control-Allow-Credentials']  = 'true';
        $header['Access-Control-Allow-Methods']  = 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
        $response                               = \think\Response::create(['code' => $code, 'message'  => $message, 'data' => $data, 'toast' => $toast], 'json')->header($header);
        throw new \think\exception\HttpResponseException($response);exit();
    }
}

if (!function_exists('pageData')){
    function pageData($pageData = []){
        if (!is_array($pageData)){ $pageData = []; }
        //param更正
        $pageData['list'] = $pageData['data']??[];
        $pageData['pageNum'] = $pageData['current_page']??1;
        $pageData['pageSize'] = $pageData['per_page']??0;
        $pageData['totalPage'] = $pageData['last_page']??0;
        //剔除不需要的param
        foreach (['data','current_page','per_page','totalPage'] as $param){ unset($pageData[$param]); }
        return $pageData;
    }
}
if (!function_exists('cache_multiple_keys')){
    function cache_multiple_keys($type,$kvs): string
    {
        $key = 'type:'.$type;
        foreach ($kvs as $k => $v){
            $key .= ':'.$k.':'.$v;
        }
        return 'type:'.$type.':'.md5($key);
    }
}
if (!function_exists('redis')){
    function redis($num=''){
        $use = 0;
        if (is_numeric($num)&&$num>=0){
            $use = $num;
        }else{
            $num = \think\facade\Config::get('redis.defaultuse','')??0;
            if (is_numeric($num)&&$num>=0){
                $use = $num;
            }
        }
        //TCP链接拼接
        $tcp = 'tcp://';
        $tcp.= \think\facade\Config::get('redis.host','');
        $tcp.= ':';
        $tcp.= \think\facade\Config::get('redis.port','');
        //新增对象
        $client = new \Predis\Client($tcp);
        $client->auth(\think\facade\Config::get('redis.password',''));
        $client->select($use);
        return $client;
    }
}
if (!function_exists('GetDomainByURL')){
    function GetDomainByURL($url=''): string
    {
        $url = parse_url($url??'');
        $u  = '';
        $u .= $url["scheme"]??'';
        $u .= '://';
        $u .= $url["host"]??'';
        if (!empty($url["port"])){
            $u .= ':';
            $u .= $url["port"];
        }
        return $u;
    }
}
if (!function_exists('createToken')){
    //全局创建 Token 方法
    function createToken($value,$type,$expire=3600*24): string
    {
        $_value = $value;
        if (is_array($_value)){ $_value = json_encode($_value);}
        $token = $type.':'.md5($type.':'.$_value.':'.time());
        \think\facade\Cache::set($token,$value,$expire);
        return $token;
    }
}
if (!function_exists('getToken')){
    //全局获取Token方法
    function getToken($token): string
    {
        if (!isEmptyStr($token)){
            $value = \think\facade\Cache::get($token);
        }
        return $value??'';
    }
}
if (!function_exists('arrDeepAssign')){
    function arrDeepAssign($keys,$value=[])
    {
        /**********************************************
         * For Example:
         * arrDeepAssign('a/b/c/d','MMMMM');
         * {
         *      "a":{
         *          "b":{
         *              "c":{
         *                  "d":"MMMMM"
         *              }
         *          }
         *      }
         *  }
         **********************************************/
        if (!empty($keys)&&is_string($keys)&&preg_match_all('([a-z-A-Z0-9\_\-]+)',$keys,$matches)){
            $keys = $matches[0];
        }
        if (!empty($keys)){
            $k = $keys[0];
            array_shift($keys);
            return [ $k => arrDeepAssign($keys,$value) ];
        }else{
            return $value;
        }
    }
}
if (!function_exists('array_group_by')){
    /**
     * 数组按某一个元素值进行分组,正如数据库的group by语句
     * @param $array
     * @param $key
     * @return array
     */
    function array_group_by($array, $key): array
    {
        $res = [];
        foreach ($array as $item) {
            $res[$item[$key]][] = $item;
        }
        return $res;
    }
}
if (!function_exists('array_by_field')){
    function array_by_field($array, $keys=''): array
    {
        if (is_string($keys)&&strlen($keys)>0) $keys = explode(',', $keys);
        return array_reduce($keys, function ($acc, $key) use ($array) {
            $key = explode(' as ', $key);
            if (!empty($key) && count($key) === 1) {
                $key[0] = trim($key[0]);
                $acc[$key[0]] = $array[$key[0]] ?? '';
            } else if (!empty($key) && count($key) === 2) {
                $key[0] = trim($key[0]);
                $key[1] = trim($key[1]);
                $acc[$key[1]] = $array[$key[0]] ?? '';
            }
            return $acc;
        }, []);
    }
}
if (!function_exists('from_array_find')){
    function from_array_find($array,$func){
        if (gettype($func)==='object'){
            foreach ($array as $item){
                if ($func($item)){
                    return $item;
                }
            }
        }
        return null;
    }
}
if (!function_exists('WechatSignature')){
    function WechatSignature($ticket,$url): array
    {
        $timestamp = time();
        $nonceStr = mt_rand(0,999);
        $nonceStr.= ':time:'.$timestamp;
        $nonceStr = md5($nonceStr);
        $nonceStr = substr($nonceStr,5,16);
        $signature = sha1(sprintf('jsapi_ticket=%s&noncestr=%s&timestamp=%s&url=%s', $ticket,$nonceStr, $timestamp,$url));
        return compact('timestamp','nonceStr','signature');
    }
}

if (!function_exists('softIncreaseNew')){
    /**
     * Created By Leroi Liu
     * Email：675667823@qq.com
     * Date：2023/2/21
     * Description：用于对软删除数据进行更新，并对旧的数据进行删除
     * @param $insertFun    ----   新插入的function
     * @param $updateFun    ----   更新的function
     * @param $deleteFun    ----   软删除的function
     * @param $updateConFun ----   判断是否已经进行了软删除，返回true，则表明已经进行了软删除
     * @param $news         ----   想要插入的新值
     * @param $newKey       ----   想要插入的新值，判断键值
     * @param $olds         ----   原来库里所有的值
     * @param $oldKey       ----   原来库里所有的值，判断键值
     * @return bool
     *
     * $news = [
     *      [ 'key1'=>'a','u'=>'vv' ],
     *      [ 'key1'=>'e','u'=>'vv' ],
     *      [ 'key1'=>'f','u'=>'vv' ]
     * ];
     * $olds = [
     *      [ 'key2'=>'a','u'=>'vv' ],
     *      [ 'key2'=>'b','u'=>'vv' ],
     *      [ 'key2'=>'c','u'=>'vv' ]
     * ];
     *
     */
    function softIncreaseNew($insertFun,$updateFun,$deleteFun,$updateConFun,$news,$newKey,$olds,$oldKey): bool
    {
        if (empty($olds)||!is_array($olds)){
            $olds = [];
        }
        if (empty($news)||!is_array($news)){
            $news = [];
        }
        $olds = array_column($olds,null,$oldKey);
        foreach ($news as $newItem){
            if (!isset($olds[$newItem[$newKey]][$oldKey])){
                //原来old里是没有的，可以插表
                $insertFun($newItem);
            }else{
                if ($updateConFun($olds[$newItem[$newKey]])){
                    //更新的条件
                    $updateFun($newItem,$olds[$newItem[$newKey]]);
                }
            }
            unset($olds[$newItem[$newKey]]);
        }
        foreach ($olds as $old){
            if (!$updateConFun($old)){
                //
                $deleteFun($old);
            }
        }
        return true;
    }
}

if (!function_exists('nowObj')){
    function nowObj(){
        $moduleName = str_replace('.', '\\', app('http')->getName());
        $controller = str_replace('.', '\\', app('request')->controller());
        $controller = "\\app\\$moduleName\\controller\\" . $controller;
        return invoke($controller);
    }
}
if (!function_exists('getRangeDates')){
    function getRangeDates($date1,$date2,$include=''): array
    {
        $arr = [];
        if ($date1&&$date2){
            $date1 = is_numeric($date1)?$date1:strtotime(substr($date1??'',0,10));
            $date2 = is_numeric($date2)?$date2:strtotime(substr($date2??'',0,10));
            if ($date1>$date2){
                $date1 = $date1 + $date2;
                $date2 = $date1 - $date2;
                $date1 = $date1 - $date2;
            }
            if ($include === 'begin'){
                $date1 += 0;
                $date2 += 0;
            }elseif ($include == 'end'){
                $date1 += 3600*24;
                $date2 += 1;
            }else if ($include == 'both_none'){
                $date1 += 3600*24;
                $date2 += 0;
            }else{
                $date1 += 0;
                $date2 += 1;
            }
            while ($date1<$date2){
                $arr[]  = date('Y-m-d',$date1);
                $date1 += 3600*24;
            }
        }
        return $arr;
    }
}
if (!function_exists('isEmptyStr')){
    function isEmptyStr($value): bool
    {
        if (isset($value)&&(is_string($value)||is_numeric($value))&&strlen($value)>0){
            return false;
        }
        return true;
    }
}
if (!function_exists('http_build_full_url')){
    function http_build_full_url($url,$options = []) :string
    {
        $url = isEmptyStr($url)?'':$url;
        $options = is_array($options)?$options:[];
        $url = parse_url($url??'');
        parse_str($url['query']??'',$url['query']);
        foreach ($options as $key => $option){
            if (!empty($option)){
                if ($key==='query'){
                    $url[$key] = array_merge(is_array($url[$key])?$url[$key]:[],is_array($option)?$option:[]);
                }else{
                    $url[$key] = $option;
                }
            }
        }
        $url['query'] = array_filter(is_array($url['query'])?$url['query']:[]);
        $url['query'] = http_build_query($url['query']);
        return sprintf('%s%s%s%s%s%s%s',
            $url['scheme'] ?? '',
            !empty($url['scheme'])?'://':'',
            $url['host'] ?? '',
            !empty($url['port']) ? ':' . $url['port'] : '',
            $url['path'] ?? '',
            !empty($url['query']) ? '?' . $url['query'] : '',
            !empty($url['fragment']) ? '#' . $url['fragment'] : ''
        );
    }
}

if (!function_exists('params_build')){
    function params_build($data,$keys,$perhaps=[],$defs=[]): array
    {
        //如果为数组数据，要进行格式化
        $data = array_map(function ($data){ return is_array($data)?json_encode($data,JSON_UNESCAPED_UNICODE):$data; },$data);
        //如果key以字符串的形式，则进行分割
        if (is_string($keys)) { $keys = explode(',', $keys); };
        if (empty($keys) || !is_array($keys)) $keys = [];
        return array_reduce($keys, function ($acc, $key) use ($data,$perhaps,$defs) {
            //如果对键值进行格式化
            if (isset($perhaps[$key])&&is_string($perhaps[$key])) $perhaps[$key] = explode(',',$perhaps[$key]);
            if (empty($perhaps[$key])){ $perhaps[$key] = []; }
            //获取可能的值
            $acc[$key] = array_reduce($perhaps[$key],function ($prev,$perhap)use($data){
                //如果在可能的键值中可以找到对应值，则直接赋值覆盖掉默认值
                return $data[$perhap]??$prev;
            },$data[$key]??($defs[$key]??''));
            $acc[$key] = trim($acc[$key]);
            return $acc;
        }, []);
    }
}
if (!function_exists('params_build_by_input')){
    function params_build_by_input($keys,$perhaps=[],$defs=[]): array
    {
        return params_build(input(),$keys,$perhaps,$defs);
    }
}
if (!function_exists('decryptDataByMc')){
    function decryptDataByMc(){
        $encode = input('data','');
        $salt = input('salt','');
        $encr = input('encr','');
        $decode = openssl_decrypt(base64_decode($encode),"AES-128-CBC",$salt,true,$encr);
        $decode = json_decode($decode,true);
        if (empty($decode['timestamp'])||!is_numeric($decode['timestamp'])){
            return [];
        }
        $diff = time()-$decode['timestamp'];
        if ($diff<0||$diff>5) return [];
        unset($decode['timestamp']);
        return $decode;

//        function randomString(length=16) {
//            try { length = parseInt(length); }catch (e){ length = 16; }
//            let str = '';
//            let codes = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz12345678";
//            let codesLength = codes.length;
//            for (let i=0;i<length;i++){
//                str += codes[Math.floor((Math.random()*codesLength))];
//            }
//            return str;
//        }
//export function encryptData(obj) {
//    if (obj instanceof Object){
//        obj.timestamp = ((new Date()).getTime()/1000).toFixed(0);
//    }
//    let salt = randomString(16);
//    let encr  = randomString(16);
//    var encrypted = CryptoJS.AES.encrypt(JSON.stringify(obj),CryptoJS.enc.Utf8.parse(salt),
//    {
//        iv:CryptoJS.enc.Utf8.parse(encr),
//        mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7
//    });
//    return { salt,encr, data:encrypted.toString() };
//}
    }
}